﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using CodeBuilderBase;
using System.Threading;

namespace CodeBuilder2009
{
    public partial class FrmMain : Form
    {
        public string DAlFront35
        {
            get
            {
                return Operate.GetApp("DAlFront35");
            }
        }

        public string HtmlFront35
        {
            get
            {
                return Operate.GetApp("HtmlFront35");
            }
        }
        public string LinqSearchObjectBehind35
        {
            get
            {
                return Operate.GetApp("LinqSearchObjectBehind35");
            }
        }

        public string LinqOperateClass35
        {
            get
            {
                return Operate.GetApp("LinqOperateClass35");
            }
        }

        public string ConnString
        {
            get
            {
                return Operate.GetApp("Conn");
            }
            set
            {
                Operate.SetApp("Conn", value);
            }
        }

        public FrmMain()
        {
            InitializeComponent();
        }

        public Dictionary<string, Dictionary<string, TableModel>> DicTables = new Dictionary<string, Dictionary<string, TableModel>>();

        ConnType getConnType()
        {
            ConnType cType = new ConnType();
            string checkValue = this.toolStripComboBox1.Text;
            switch(checkValue)
            {
                case "SQL2005":
                    {
                        cType = ConnType.Sql2005;
                    }
                    break;
                case "SQL2000":
                    {
                        cType = ConnType.Sql2000;
                    }
                    break;
                case "OLEDB":
                    {
                        cType = ConnType.OleDb;
                    }
                    break;
            }
            return cType;
        }

        private void button_Connect_Click(object sender, EventArgs e)
        {
            ConnType cType = getConnType();
            if (cType == ConnType.OleDb)
            {
                MessageBox.Show("目前只支持Sql数据库");
                return;
            }
            else
            {
                Thread mainThread = new Thread(new ParameterizedThreadStart(GetValues));
                mainThread.Start(cType);
            }
        }

        private void GetValues(object cT)
        {
            ConnType cType = (ConnType)cT;
            GetReady ready = new GetReady(delegate { this.button_Connect.Enabled = false; });
            GetReady readyOver = new GetReady(delegate { this.button_Connect.Enabled = true; });
            this.button_Connect.Invoke(ready);
            DicTables.Clear();
            Operate op = new Operate();
            string err = "";
            if (!op.TestConn(cType, this.txtConnString.Text, out err))
            {
                MessageBox.Show("数据库连接失败：" + err);
                this.button_Connect.Invoke(readyOver);
                return;
            }
            else
            {
                ConnString = this.txtConnString.Text;
            }
            List<TableModel> list = new List<TableModel>();
            try
            {
                list = op.GetTableModelListAll(cType);
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("sysproperties"))
                {
                    if (MessageBox.Show("获取数据失败,可能是连接方式出错,是否切换到 SQL2005 方式试试?", "是否切换到 SQL2005 方式试试", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        GetReady changeConnType = new GetReady(delegate{this.toolStripComboBox1.SelectedIndex = (int)ConnType.Sql2005; });

                        this.Invoke(changeConnType);

                        GetValues(ConnType.Sql2005);
                    }
                }
                else if (ex.Message.Contains("sys.extended_properties"))
                {
                    if (MessageBox.Show("获取数据失败,可能是连接方式出错,是否切换到 SQL2000 方式试试?", "是否切换到 SQL2000 方式试试", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) == DialogResult.Yes)
                    {
                        GetReady changeConnType = new GetReady(delegate { this.toolStripComboBox1.SelectedIndex = (int)ConnType.Sql2000; });
                        this.Invoke(changeConnType);
                        GetValues(ConnType.Sql2000);
                    }
                }
                else
                {
                    MessageBox.Show("获取数据失败:" + ex.Message+"");
                }
                this.button_Connect.Invoke(readyOver);
                return;
            }

            if (list.Count > 0)
            {
                foreach (TableModel tm in list)
                {
                    if (!DicTables.ContainsKey(tm.TableName))
                    {
                        DicTables.Add(tm.TableName, new Dictionary<string, TableModel>());
                    }
                    DicTables[tm.TableName].Add(tm.ColumName, tm);
                }
                FillTreeViewEventHandle de = new FillTreeViewEventHandle(FillTreeView);
                this.txtTreeView.Invoke(de);
            }
            else
            {
                MessageBox.Show("数据库里无任何表！");
                this.button_Connect.Invoke(readyOver);
                return;
            }
            this.button_Connect.Invoke(readyOver);
        }
        public delegate void FillTreeViewEventHandle();

        private delegate void GetReady();

        private void FillTreeView()
        {
            this.txtTreeView.Nodes.Clear();
            foreach (KeyValuePair<string, Dictionary<string, TableModel>> kp in DicTables)
            {
                this.txtTreeView.Nodes.Add(kp.Key, kp.Key);
                foreach (KeyValuePair<string, TableModel> tt in kp.Value)
                {
                    this.txtTreeView.Nodes[kp.Key].Nodes.Add(tt.Key, tt.Value.ColumName + " " + tt.Value.ColumType + (tt.Value.ColumByteCount.Equals("") ? "" : "(" + tt.Value.ColumByteCount + "," + tt.Value.NumberOfDecimalPlaces + ")"));
                }
            }
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            this.txtConnString.Text = ConnString;
            this.toolStripComboBox1.SelectedIndex = 0;
        }

        private void txtTreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {
            int level = e.Node.Level;
            
            if (level == 0)
            {
                List<TableModel> list = new List<TableModel>();
                Dictionary<string, TableModel> dic = new Dictionary<string, TableModel>();
                dic = DicTables[e.Node.Name];
                foreach (KeyValuePair<string, TableModel> kv in dic)
                {
                    list.Add(kv.Value);
                }
                this.txtGridView.DataSource = list;
            }
            else if (level == 1)
            {
                TableModel tm = DicTables[e.Node.Parent.Name][e.Node.Name];
                List<ColumAttribute> lit = GetAttribute(tm);
                this.txtGridView.DataSource = lit;
            }
            
        }

        private static List<ColumAttribute> GetAttribute(TableModel tm)
        {
            List<ColumAttribute> lit = new List<ColumAttribute>();

            lit.Add(new ColumAttribute(tm.ColumName, "(名称)"));
            lit.Add(new ColumAttribute(tm.DefaultValue, "默认值或绑定"));
            lit.Add(new ColumAttribute(tm.ColumType, "数据类型"));
            lit.Add(new ColumAttribute(tm.IsAllowNull, "允许空"));
            lit.Add(new ColumAttribute(tm.IsIdentity, "标识符规范"));
            lit.Add(new ColumAttribute(tm.ColumByteCount, "大小"));
            lit.Add(new ColumAttribute(tm.IsPK, "主键"));
            lit.Add(new ColumAttribute(tm.TableName, "所属表名"));
            lit.Add(new ColumAttribute(tm.ColumRemark, "说明"));
            return lit;
        }

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (this.tabControl1.SelectedIndex > 0 &&( this.txtTreeView.SelectedNode == null || this.txtTreeView.SelectedNode.Level > 0))
            {
                MessageBox.Show("您必须先选择一个表来操作！");
                this.tabControl1.SelectedIndex = 0;
                return;
            }
        }

        private void tabPageDALLinq_Enter(object sender, EventArgs e)
        {
            if (this.txtTreeView.SelectedNode != null && this.txtTreeView.SelectedNode.Level == 0)
            {
                TreeNode nod = this.txtTreeView.SelectedNode;
                Dictionary<string, TableModel> dic = new Dictionary<string, TableModel>();
                dic = DicTables[nod.Name];
#region 清除旧数据
                this.txtTreeViewLinqDAL.Nodes.Clear();
                this.txtDALLinqAutoCode.Items.Clear();
#endregion
                string nodeKey = "";
                foreach (TableModel tt in dic.Values)
                {
                    if (!this.txtTreeViewLinqDAL.Nodes.ContainsKey(tt.TableName))
                    {
                        this.txtTreeViewLinqDAL.Nodes.Add(tt.TableName, tt.TableName);
                        nodeKey = tt.TableName;
                    }
                    this.txtTreeViewLinqDAL.Nodes[tt.TableName].Nodes.Add(tt.ColumName, tt.ColumName + " " + tt.ColumType + (tt.ColumByteCount.Equals("") ? "" : "(" + tt.ColumByteCount + "," + tt.NumberOfDecimalPlaces + ")"));
                    if (tt.IsPK.Equals("√") || tt.IsIdentity.Equals("√") || tt.ColumType.ToUpper().Contains("INT"))
                    {
                        this.txtDALLinqAutoCode.Items.Add(new KeyValuePair<string,string>(tt.ColumName,tt.ColumType));
                    }
                    this.txtDALLinqAutoCode.SelectedIndex = 0;
                    
                }
                this.txtTreeViewLinqDAL.Nodes[nodeKey].Expand();
                this.txtDALLinqClassName.Text = DAlFront35 + nodeKey;
                this.txtTableObjectName.Text = nodeKey + LinqSearchObjectBehind35;
                this.txtLinqOperateName.Text = LinqOperateClass35;
            }
        }

        private void button_BuildDAL_Click(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            string nameSpace = this.txtDALLinqNameSpace.Text;
            string className = this.txtDALLinqClassName.Text;
            string linqOpName = this.txtLinqOperateName.Text;
            string tableObjectName = this.txtTableObjectName.Text;
            KeyValuePair<string, string> key = (KeyValuePair<string, string>)this.txtDALLinqAutoCode.SelectedItem;
            if (nameSpace == string.Empty)
            {
                MessageBox.Show("命名空间不能为空！");
                this.txtDALLinqNameSpace.Focus();
                return;
            }
            else if (className == string.Empty)
            {
                MessageBox.Show("类名不能为空！");
                this.txtDALLinqClassName.Focus();
                return;
            }
            else if (linqOpName == string.Empty)
            {
                MessageBox.Show("Linq操作类不能为空！");
                this.txtLinqOperateName.Focus();
                return;
            }
            else if (tableObjectName == string.Empty)
            {
                MessageBox.Show("Linq实体类不能为空！");
                this.txtTableObjectName.Focus();
                return;
            }
            CodeBuild cb = new CodeBuild();
            this.txtDALLinqCode.Text = cb.DAlLinqCode(nameSpace, className, tableObjectName, key, linqOpName);
            Operate.SetApp("LinqOperateClass35", this.txtLinqOperateName.Text);
        }

        private void txtDALLinqCode_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            this.txtDALLinqCode.SelectAll();
        }

        private void txtTreeViewLinqDAL_AfterSelect(object sender, TreeViewEventArgs e)
        {
            int level = e.Node.Level;
            if (level == 1)
            {
                TableModel tm = DicTables[e.Node.Parent.Name][e.Node.Name];
                List<ColumAttribute> lit = GetAttribute(tm);
                this.txtGridViewAttrubute.DataSource = lit;
            }
            else
            {
                this.txtGridViewAttrubute.DataSource = null;
            }
        }

        private void 退出XToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Dispose(true);
        }

        private void 关于AToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new AboutUS().ShowDialog(this);
        }

        private void 选项OToolStripMenuItem_Click(object sender, EventArgs e)
        {
            new FrmOption().ShowDialog(this);
        }
    }
}
